Skip to content
This repository was archived by the owner on Sep 17, 2025. It is now read-only.

Add Stackdriver Trace V2 models#87

Merged
liyanhui1228 merged 21 commits intocensus-instrumentation:masterfrom
liyanhui1228:stackdriver-v2
Dec 8, 2017
Merged

Add Stackdriver Trace V2 models#87
liyanhui1228 merged 21 commits intocensus-instrumentation:masterfrom
liyanhui1228:stackdriver-v2

Conversation

@liyanhui1228
Copy link
Copy Markdown
Contributor

@liyanhui1228 liyanhui1228 commented Nov 28, 2017

For #78

@liyanhui1228 liyanhui1228 changed the title [WIP] Add Stackdriver Trace V2 models Add Stackdriver Trace V2 models Nov 29, 2017
Copy link
Copy Markdown
Member

@chingor13 chingor13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you missing the MessageEvent model?

Also, it seems that this PR is just finishing implementing the OpenCensus trace.proto models as they aren't being used in the StackdriverExporter yet.

Comment thread trace/opencensus/trace/attributes.py Outdated

def _format_attribute_value(value):
if type(value).__name__ == 'str':
value_type = 'string_value'
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string_value value is a TruncatableString which has a value field.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Done.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Python 2/3 compatibility, we could check for bytes, str, and unicode, and convert them to str using 'utf-8' encoding. Just doing str might be good enough for now, though.`

@liyanhui1228
Copy link
Copy Markdown
Contributor Author

liyanhui1228 commented Nov 30, 2017

Yes will change the StackdriverExporter to use the models in later commits.

@liyanhui1228 liyanhui1228 changed the title Add Stackdriver Trace V2 models [WIP] Add Stackdriver Trace V2 models Dec 1, 2017
Comment thread trace/opencensus/trace/attributes.py Outdated
if type(value).__name__ == 'str':
value_type = 'string_value'
value = _get_truncatable_str(value)
elif type(value).__name__ == 'int':
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can just do if isinstance(value, int) I think. Same for bool and str

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isinstance(True, int) will also return True. Changed to put the check for bool at the first if statement and check int later.

Comment thread trace/opencensus/trace/attributes.py Outdated

def _format_attribute_value(value):
if type(value).__name__ == 'str':
value_type = 'string_value'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Python 2/3 compatibility, we could check for bytes, str, and unicode, and convert them to str using 'utf-8' encoding. Just doing str might be good enough for now, though.`


:type attributes: dict
:param attributes: The set of attributes. Each attribute's key can be up
to 128 bytes long. The value can be a string up to 256
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we check and enforce these limits in the code?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added check for length of the attribute key. The length of string value is checked in opencensus.trace.utils._get_truncatable_str when converting to TruncatableString.


self.attributes = attributes

def set_attribute(self, key, value):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any need for a "delete attribute" in the API? I think probably no, but I wanted to mention it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Comment thread trace/opencensus/trace/attributes.py Outdated
if attributes is None:
attributes = {}

self.attributes = attributes
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably copy the attributes dictionary instead of taking it by reference, so that the caller can't accidentally change our internal dictionary. E.g. something like

self.attributes = dict(attributes or {})

This is not absolutely required, but it's a good pattern to follow in general, and especially in constructors, to avoid two pieces of code sharing a list or dict without realizing it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Done.

value = self.attributes.get(key)
value_json = _format_attribute_value(value)
attributes_json[key] = value_json

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not required, but it you like, you could also do this:

attributes_json = {key: _format_attribute_value(value) 
                   for key, value in self.attributes}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

"""
:type trace: dict
:param trace: Trace collected.
:type spans: dict
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a private method? Otherwise, we should probably explain the translation a bit in the comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment thread trace/opencensus/trace/span.py Outdated

def add_time_event(self, time_event):
"""Add a TimeEvent."""
self.time_events.append(time_event)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to check that this is a TimeEvent and throw TypeError otherwise. Same as link below.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@duggelz
Copy link
Copy Markdown

duggelz commented Dec 5, 2017

You are going to have a massive merge conflict between this and the big rename. Which one are you going to do first?

@liyanhui1228
Copy link
Copy Markdown
Contributor Author

The Stackdriver V2 won't be included in the first release. So I'll merge the restructure PR first.

Comment thread trace/opencensus/trace/link.py Outdated
self.attributes = attributes

def format_link_json(self):
"""Conver a Link object to json format."""
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conver -> Convert

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Comment thread trace/opencensus/trace/utils.py Outdated
count.
"""
str_bytes = str_to_convert.encode(UTF8)
str_len = len(str_bytes)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems kind of problematic, because you could convert a code point to a 2 or 3 byte utf-8 sequence, and then truncate the string in the middle of that sequence, creating an invalid string that causing an exception to be thrown.

But I think you can get around this by changing the code below to

truncated = str_bytes.decode(UTF8, errors='ignore')

This seemed to do the right thing in both Python 2 and 3. Can you add a unit test where you call this on a string with 127 ascii characters followed by a some non-ascii characters?

I used the following code to play with truncation: ('\u2603\u2603'.encode('utf-8')[0:5]).decode('utf-8', errors='ignore').

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation! Added the unit test for that.

Comment thread trace/opencensus/trace/utils.py Outdated
if str_len > limit:
str_bytes = str_bytes[:limit]

result = str_bytes.decode(UTF8)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment here as above. Perhaps one of these functions could call the other, or have a helper function that takes a (string, limit) and returns (truncated_string, truncated_byte_count)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion, done.

@liyanhui1228 liyanhui1228 changed the title [WIP] Add Stackdriver Trace V2 models Add Stackdriver Trace V2 models Dec 7, 2017
Copy link
Copy Markdown

@duggelz duggelz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM except I'm curious about the randint change

than 0 and unique within a trace.
"""
span_id = random.getrandbits(64)
span_id = random.randint(10**15, 10**16 - 1)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did this change?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the V2 API only accepts 16-digit span_id, but we can also trim the span_id in the stackdriver_exporter.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Maybe document that rationale, and/or make those named constants.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Comment thread opencensus/trace/utils.py Outdated
:returns: The string it self if not exceeded length, or truncated string
if exceeded and the truncated byte count.
"""
if limit is None:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could also just do limit=MAX_LENGTH above in the function signature.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@liyanhui1228 liyanhui1228 merged commit 40af615 into census-instrumentation:master Dec 8, 2017
@liyanhui1228 liyanhui1228 deleted the stackdriver-v2 branch December 8, 2017 17:53
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants